#pragma once

#include <math.h>    
#include <iostream>  
#include <vector>  
using namespace std;

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;

class calTwoPoint  
{  
public:  
    calTwoPoint(CvPoint pointO,CvPoint pointA);  
    ~calTwoPoint(void);  
  
    CvPoint2D32f get_unit_vector();//根据两点获取单位向量  
    CvPoint2D32f get_unit_vertical_vector(bool type = true);//根据两点获取垂直单位向量  
    double get_distance ();    //获取两点之间的距离   
    double get_angle() ;       //已知2个坐标点，求从 0------->x 逆时针需旋转多少角度到该位置  
    double get_line_angle();     
    CvPoint point_add();       //两点相加  
private:  
    CvPoint pointO;  
    CvPoint pointA;  
  
    double get_angle2(CvPoint pointO,CvPoint pointA)  ;  
};

calTwoPoint::calTwoPoint(CvPoint pointO,CvPoint pointA)  
{  
    this->pointO = pointO;  
    this->pointA = pointA;  
}  
  
  
calTwoPoint::~calTwoPoint(void)  
{  
}  
  
/************************************************************************  
*函数名：        get_angle  
*  
*函数作用：      已知2个坐标点，求从 0------->x 逆时针需旋转多少角度到该位置  
*  
*                   |  
*                   |  
*                   |  
*                   |                
*------------------------------------> x  
*                   | 0              
*                   |  
*                   |  
*                   |  
*                   v  
*                   y  
*                     
*函数参数：  
*CvPoint2D32f pointO  - 起点  
*CvPoint2D32f pointA  - 终点  
*  
*函数返回值：  
*double         向量OA，从 0------->x 逆时针需旋转多少角度到该位置  
**************************************************************************/    
double calTwoPoint:: get_angle()    
{    
    return get_angle2(pointO,pointA);    
}  
  
double calTwoPoint :: get_angle2(CvPoint pointO,CvPoint pointA)    
{    
    double angle = 0;    
    CvPoint point;    
    double temp;    
  
    point = cvPoint((pointA.x - pointO.x), (pointA.y - pointO.y));//pointAdd(pointA,pointMultiply(pointO,-1));    
  
    if ((0==point.x) && (0==point.y))    
    {    
        return 0;    
    }    
  
    if (0==point.x)    
    {    
        angle = 90;    
        return angle;    
    }    
  
    if (0==point.y)    
    {    
        angle = 0;    
        return angle;    
    }    
  
    temp = fabsf(float(point.y)/float(point.x));    
    temp = atan(temp);    
    temp = temp*180/CV_PI ;    
  
    if ((0<point.x)&&(0<point.y))    
    {    
        angle = 360 - temp;    
        return angle;    
    }    
  
    if ((0>point.x)&&(0<point.y))    
    {    
        angle = 360 - (180 - temp);    
        return angle;    
    }    
  
    if ((0<point.x)&&(0>point.y))    
    {    
        angle = temp;    
        return angle;    
    }    
  
    if ((0>point.x)&&(0>point.y))    
    {    
        angle = 180 - temp;    
        return angle;    
    }    
  
    printf("sceneDrawing :: getAngle error!");    
    return -1;    
}  
  
double calTwoPoint :: get_line_angle()    
{    
    double roadAngle = 0;    
  
    if (pointO.x < pointA.x)  
    {  
        return get_angle2(cvPoint(pointA.x, pointA.y),cvPoint(pointO.x, pointO.y));   
    }  
  
    else if ((pointO.x == pointA.x) && (pointO.y < pointA.y))  
    {  
        return get_angle2(cvPoint(pointA.x, pointA.y),cvPoint(pointO.x, pointO.y));   
    }  
  
    else  
    {  
        return get_angle2(cvPoint(pointO.x, pointO.y),cvPoint(pointA.x, pointA.y));   
    }  
  
}  
  
/************************************************************************ 
*函数名：        get_unit_vector 
* 
*函数作用：      根据两点获取单位向量 
* 
*函数参数： 
*CvPoint pointO  - 起点 
*CvPoint pointA  - 终点 
* 
*函数返回值： 
*CvPoint2D32f    两点之间的单位向量 
**************************************************************************/  
CvPoint2D32f calTwoPoint :: get_unit_vector ()  
{  
    CvPoint2D32f point;  
    float distance;  
    distance = powf((pointO.x - pointA.x),2) + powf((pointO.y - pointA.y),2);  
    distance = sqrtf(distance);  
  
    point.x = float(pointA.x - pointO.x)/distance;  
    point.y = float(pointA.y - pointO.y)/distance;  
  
    return point;  
}  
  
/************************************************************************ 
*函数名：        get_unit_vertical_vector 
* 
*函数作用：      根据两点获取垂直单位向量 
* 
*函数参数： 
*CvPoint pointO  - 起点 
*CvPoint pointA  - 终点 
*int type        - 0 表示方向是向左上 
* 
*函数返回值： 
*CvPoint2D32f    两点之间的垂直单位向量 
**************************************************************************/  
CvPoint2D32f  calTwoPoint :: get_unit_vertical_vector (bool type )  
{  
    CvPoint point;  
    CvPoint2D32f p;  
  
    point.x = pointA.x - pointO.x;  
    point.y = pointA.y - pointO.y;  
  
    if ((0 == point.x) && ( 0 == point.y))  
    {  
        p.x = 0;  
        p.y = 0;  
        printf("  getUnitVerticalVector : error, ( 0 == point.x) && if ( 0 == point.y)");  
  
        return p;  
    }  
  
    if ( 0 == point.x)  
    {  
        if (true == type)//垂直向量的y分量小于于0，向左上  
        {  
            p.x = -1;  
        }  
        else  
        {  
            p.x = -1;  
        }  
        p.y = 0;  
  
        return p;  
    }  
  
    if ( 0 == point.y)//垂直向量的y分量小于于0，向左上  
    {  
        p.x = 0;  
        p.y = -1;//图片中越往下越大，所以 y坐标= -1 表示向上  
  
        return p;  
    }  
  
    //求垂直单位向量p  
    /* 
    float pow(float x, float y);  
    原型：在TC2.0中原型为extern float pow(float x, float y); ， 
    而在VC6.0中原型为double pow( double x, double y ); 
    头文件：math.h/cmath(C++中) 
    功能：计算x的y次幂。 
    返回值：x应大于零，返回幂指数的结果。 
    返回类型：double型，int，float会给与警告！   
    */  
    p.y = - fabsf((point.x * 1.0f)/sqrtf((powf(point.x, 2)) + powf(point.y, 2)));  
    p.x = - ((point.y * 1.0f)/point.x)*p.y;  
  
    if (true == type)//垂直向量的y分量小于0，向左上  
    {  
        if (0 < p.y)  
        {  
            p.x = - p.x;  
            p.y = - p.y;  
        }  
    }  
    else  
    {  
        if (0 > p.y)//垂直向量的y分量大于0，向下  
        {  
            p.x = - p.x;  
            p.y = - p.y;  
        }  
    }  
  
    return p;  
}  
  
/************************************************************************  
*函数名：        get_distance  
*  
*函数作用：      获取两点之间的距离  
*  
*函数参数：  
*CvPoint2D32f pointO  - 起点  
*CvPoint2D32f pointA  - 终点  
*  
*函数返回值：  
*double           两点之间的距离  
**************************************************************************/    
double calTwoPoint :: get_distance ()    
{    
    double distance;    
    distance = powf((pointO.x - pointA.x),2) + powf((pointO.y - pointA.y),2);    
    distance = sqrtf(distance);    
    
    return distance;    
}    
  
/************************************************************************  
*函数名：        point_add  
*  
*函数作用：      两点相加  
*  
*函数参数：  
*CvPoint2D32f point1  - 起点  
*CvPoint2D32f point2  - 终点  
*  
*函数返回值：  
*CvPoint2D32f         两点相加结果  
**************************************************************************/    
CvPoint calTwoPoint :: point_add()    
{    
    CvPoint pointOut;    
    
    pointOut.x = pointO.x + pointA.x;    
    pointOut.y = pointO.y + pointA.y;    
    
    return pointOut;    
}  

